﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Web;
using System.Collections;
using System.Security.Cryptography;
using NEvoWeb.Modules.NB_Store;

namespace Satrabel.Modules.NB_Store.Gateway
    
    
{
    public class GatewayOgone : GatewayInterface
    {



        public override string GetButtonHtml(int PortalID, int OrderID, string Lang)
        {
            string strHTML = "";
            SettingsController objSCtrl = new SettingsController();
            NB_Store_SettingsInfo objSInfo;
            // get the gateway settings from the NB_Store settings table
            objSInfo = objSCtrl.GetSetting(PortalID, "Ogone.gateway", Lang);

            if (!(objSInfo == null))
            {
                // Move the xml format settingn into the a hashtable so we can use it easily.
                Hashtable setParams = createSettingsTable(objSInfo.SettingValue);

                // Build Html to display the payment button.
                strHTML = ("<INPUT TYPE=IMAGE NAME=OGONE BORDER=0 SRC=\"" + (setParams["ButtonImageURL"] + "\"/>"));
            }
            return strHTML;
        }



        public override void AutoResponse(int PortalID, System.Web.HttpRequest Request)
        {
            try
            {
                SettingsController objSCtrl = new SettingsController();
                OrderController objOCtrl = new OrderController();
                ProductController objPCtrl = new ProductController();
                NB_Store_OrdersInfo objOInfo;
                NB_Store_SettingsInfo objSInfo;


                string SHAPass = "";
                objSInfo = objSCtrl.GetSetting(PortalID, "Ogone.gateway", "None");
                if (!(objSInfo == null))
                {
                    Hashtable setParams = createSettingsTable(objSInfo.SettingValue);
                    SHAPass = "" + setParams["SHAPass"];
                }


                string OrderID = Request.Form["orderID"];
                string Status = Request.Form["Status"];
                string CartID = Request.Form["CartId"];
                string userLang = Request.Form["Lang"];

                string[] SHAkeys = new string[] { "NCERROR", "orderID", "PAYID", "STATUS" };
                string SHAtexte = "";
                string SHASign = Request.Form["SHASign"];
                for (int i = 0; i < SHAkeys.Length;i++ )
                    SHAtexte = SHAtexte + SHAkeys[i].ToUpper() + "=" + Request.Form[SHAkeys[i]] + SHAPass;
                //SharedFunctions.UpdateLog(("AutoResponse SHAtexte = " + SHAtexte));
                if (CalcSHA(SHAtexte) == SHASign)
                    SharedFunctions.UpdateLog(("AutoResponse = " + OrderID + "/" + Status + "/" + CartID + "/" + userLang+"/ok"));
                else
                    SharedFunctions.UpdateLog(("AutoResponse = " + OrderID + "/" + Status + "/" + CartID + "/" + userLang+"/ko"));

                // clear cart parameters 
                CartController objCCtrl = new CartController();
                NB_Store_CartInfo objCInfo = objCCtrl.GetCart(CartID);
                if (objCInfo != null)
                {
                    objCInfo.BankTransID = -1;
                    objCInfo.BankHtmlRedirect = "";
                    objCCtrl.UpdateObjCart(objCInfo);
                }
                objOInfo = objOCtrl.GetOrder(int.Parse(OrderID));
                if (objOInfo != null)
                {
                    // check that the order is valid. (Not yet been processed)
                    if (!objOInfo.OrderIsPlaced)
                    {
                        if (Status[0] == '9')
                        {
                            //  check if order has already been processed
                            if (!objOInfo.OrderIsPlaced)
                            {
                                // remove qty in trans
                                objPCtrl.UpdateStockLevel(objOInfo.OrderID);
                                // set order status to Payed
                                objOInfo.OrderStatusID = 40;
                                int UsrID = objOInfo.UserID;
                                if ((UsrID == -1))
                                {
                                    UsrID = 0;
                                }
                                objOInfo.OrderNumber = (PortalID.ToString("00") + ("-"
                                            + (UsrID.ToString("0000#") + ("-"
                                            + (objOInfo.OrderID.ToString("0000#") + ("-" + objOInfo.OrderDate.ToString("yyyyMMdd")))))));
                                objOInfo.OrderIsPlaced = true;
                                objOCtrl.UpdateObjOrder(objOInfo);


                                // update in email
                                string merchant_language;
                                
                                string language = userLang;
                                objSInfo = objSCtrl.GetSetting(PortalID, "Ogone.gateway", "None");
                                if (!(objSInfo == null))
                                {
                                    Hashtable setParams = createSettingsTable(objSInfo.SettingValue);
                                    merchant_language = "" + setParams["MerchantLanguage"];
                                }

                                SharedFunctions.SendEmailToClient(PortalID, SharedFunctions.GetClientEmail(PortalID, objOInfo), objOInfo.OrderNumber, objOInfo, "paymentOK.email", language);
                                SharedFunctions.SendEmailToManager(PortalID, objOInfo.OrderNumber, objOInfo, "paymentOK.email");
                            }
                        }
                        else
                        {
                            // check if order has already been cancelled
                            if (objOInfo.OrderStatusID != 30)
                            {
                                // remove qty in trans
                                objPCtrl.RemoveModelQtyTrans(objOInfo.OrderID);
                                // set order status to cancelled
                                objOInfo.OrderStatusID = 30;
                                objOCtrl.UpdateObjOrder(objOInfo);
                            }
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                //DotNetNuke.Services.Exceptions.Logxception(ex);
                SharedFunctions.UpdateLog(("Ogone Exception " + ex.ToString()));
                
                // something went wrong, lets log the error...
                SharedFunctions.SendEmailToAdministrator(PortalID, "Ogone AutoReturn ERROR", ex.ToString());
            }
        }


        public override string GetCompletedHtml(int PortalID, int UserID, System.Web.HttpRequest Request) {
                       

            SettingsController objSCtrl = new SettingsController();
            OrderController objOCtrl = new OrderController();
            ProductController objPCtrl = new ProductController();
            NB_Store_OrdersInfo objOInfo;
            NB_Store_SettingsTextInfo objSInfo;
            
            string rtnMsg = "";
            string orderIDStr = Request.QueryString["ordID"];
            string status = Request.QueryString["STATUS"];
            int orderID;
            bool ok = int.TryParse(orderIDStr, out orderID);

            // http://www.barrygton.com/fr/Caddie/tabid/190/stg/5/Default.aspx?orderID=1039&STATUS=9&PAYID=9588295&NCERROR=0&COMPLUS=dd48c0f7-2bf1-4e63-97c8-cbdbac47d347&SHASIGN=6DDB2180415D66D28C15824A39BF35E968235393

            /*
            foreach (string key in Request.QueryString.Keys) {
                rtnMsg = rtnMsg + Request.QueryString[key];
            }
            */
            

            // set rtnMsg to security error message
            objSInfo = objSCtrl.GetSettingsText(PortalID, "paymentSECURITY.text", SharedFunctions.GetCurrentCulture());
            rtnMsg = objSInfo.SettingText;
            if (ok) {
                objOInfo = objOCtrl.GetOrder(orderID);
                if (!(objOInfo == null)) {
                    if ((objOInfo.UserID == UserID)) {
                        if (status == "ACCEPT" ) { // succes
                            /*
                            if (!objOInfo.OrderIsPlaced && objOInfo.OrderStatusID != 30) {
                                // remove qty in trans
                                objPCtrl.UpdateStockLevel(objOInfo.OrderID);
                                // set order status to Payed
                                objOInfo.OrderStatusID = 45;
                                int UsrID = objOInfo.UserID;
                                if ((UsrID == -1)) {
                                    UsrID = 0;
                                }
                                objOInfo.OrderNumber = (PortalID.ToString( "00") + ("-" 
                                            + (UserID.ToString("0000#") + ("-" 
                                            + (objOInfo.OrderID.ToString("0000#") + ("-" + objOInfo.OrderDate.ToString("yyyyMMdd")))))));
                                objOInfo.OrderIsPlaced = true;
                                objOCtrl.UpdateObjOrder(objOInfo);
                                SharedFunctions.SendEmailToManager(PortalID, objOInfo.OrderNumber, objOInfo, "paymentunverified.email");
                            }
                             */
                            // set completed order message
                            objSInfo = objSCtrl.GetSettingsText(PortalID, "paymentOK.text", SharedFunctions.GetCurrentCulture());
                            rtnMsg = objSInfo.SettingText;
                        }
                        else 
                        {
                            if (!objOInfo.OrderIsPlaced) {
                                // check if order has already been cancelled
                                /*
                                if (objOInfo.OrderStatusID != 30) {
                                    // remove qty in trans
                                    objPCtrl.RemoveModelQtyTrans(objOInfo.OrderID);
                                    // set order status to cancelled
                                    objOInfo.OrderStatusID = 30;
                                    objOCtrl.UpdateObjOrder(objOInfo);
                                }
                                 */
                                // set Cancel order message
                                objSInfo = objSCtrl.GetSettingsText(PortalID, "paymentFAIL.text", SharedFunctions.GetCurrentCulture());
                                rtnMsg = objSInfo.SettingText;
                            }
                        }
                         
                        TokenStoreReplace objTR = new TokenStoreReplace(objOInfo, SharedFunctions.GetMerchantCulture(PortalID));
                        rtnMsg = objTR.DoTokenReplace(rtnMsg);
                    }
                }
            }
            return rtnMsg;
        }



        public override bool GetBankClick(int PortalID, System.Web.HttpRequest Request)
        {
            // test if Paypal button has been clicked
            if (!(Request.Form["OGONE.x"] == null))
            {
                return true;
            }
            else
            {
                return false;
            }
        }



        public override void SetBankRemotePost(int PortalID, int OrderID, string Lang, System.Web.HttpRequest Request) {
            RemotePost RPost = new RemotePost();
            SettingsController objSCtrl = new SettingsController();
            
            NB_Store_SettingsInfo objSInfo = objSCtrl.GetSetting(PortalID, "Ogone.gateway", Lang);

            if (!(objSInfo == null)) {
                Hashtable setParams = createSettingsTable(objSInfo.SettingValue);

                                
                string acceptURL = ""+setParams["acceptURL"];
                string declineURL = ""+setParams["declineURL"];
                string exceptionURL = ""+setParams["exceptionURL"];
                string cancelURL = ""+setParams["cancelURL"];
                
                string backURL = ""+setParams["backURL"];
                
                string OgoneURL = ""+setParams["paymentURL"];

                string SHAPass = ""+setParams["SHAPass"];

                string PSPID = ""+setParams["PSPID"];


                string OgoneCartName = ""+setParams["CartName"];
                //string PayPalButtonURL = setParams["ButtonImageURL"];
                string OgoneCurrency = ""+setParams["Currency"];
                string MerchantLanguage = ""+setParams["MerchantLanguage"];

                

                OrderController objOCtrl = new OrderController();
                NB_Store_OrdersInfo oInfo = objOCtrl.GetOrder(OrderID);
                if (!(oInfo == null)) {
                    acceptURL = acceptURL.Replace("[ORDERID]", oInfo.OrderID.ToString());
                    declineURL = declineURL.Replace("[ORDERID]", oInfo.OrderID.ToString());
                    exceptionURL = exceptionURL.Replace("[ORDERID]", oInfo.OrderID.ToString());
                    cancelURL = cancelURL.Replace("[ORDERID]", oInfo.OrderID.ToString());
                    backURL = backURL.Replace("[ORDERID]", oInfo.OrderID.ToString());

                    decimal amount = oInfo.CartTotal;
                    
                    string ClientName = "";
                    string Zip = ""; 
                    string Addr = "";
                    string Town = "";
                    string City = "";
                    string Phone = "";

                    NB_Store_AddressInfo AdresseInfo = objOCtrl.GetOrderAddress(oInfo.BillingAddressID);
                    if (AdresseInfo != null)
                    {
                        ClientName = AdresseInfo.CompanyName;
                        Addr = AdresseInfo.Address1;
                        Town = AdresseInfo.City;
                        Zip = AdresseInfo.PostalCode;
                        City = AdresseInfo.CountryCode;
                        Phone = AdresseInfo.Phone1;
                    }
                   

                    System.Xml.XmlDataDocument xmlDoc = new System.Xml.XmlDataDocument();
                   
                    System.Xml.XmlNodeList xmlNodList;
                    Hashtable addpar = new Hashtable();
                    xmlDoc.LoadXml(objSInfo.SettingValue);
                    xmlNodList = xmlDoc.SelectNodes("root/optionalfields/*");
                    foreach (System.Xml.XmlNode xmlNod in xmlNodList)
                    {
                        addpar.Add(xmlNod.Name, xmlNod.InnerText);
                    }

                    // update stock tranction in progress
                    ProductController objPCtrl = new ProductController();
                    objPCtrl.UpdateModelQtyTrans(oInfo.OrderID);
                    // set order status to redirect to bank
                    oInfo.OrderStatusID = 20;
                    objOCtrl.UpdateObjOrder(oInfo);
                    objSInfo = objSCtrl.GetSetting(PortalID, "gateway.loadimage", "None");
                    
                    NB_Store_CartInfo objCInfo = CurrentCart.GetCurrentCart(PortalID);

                    


                    RPost = new RemotePost();

                    RPost.Url = OgoneURL;
                    OgonePost(RPost , oInfo.OrderID.ToString(), PSPID, OgoneURL, amount, OgoneCurrency, 
                                SHAPass, MerchantLanguage,
                                objCInfo.CartID.ToString(), 
                                OgoneCartName, ClientName, oInfo.Email, Zip, Addr, Town, City, Phone,
                                acceptURL, declineURL, exceptionURL, cancelURL, SharedFunctions.GetCurrentCulture(),
                                addpar);

                    
                    
                    // Save the report html into the cart, the user will be redirect to this 
                    objCInfo.BankHtmlRedirect = RPost.GetPostHtml(objSInfo.SettingValue);
                    CurrentCart.Save(objCInfo);
                    SharedFunctions.UpdateLog(("Ogone URL = " + RPost.Url));
                }
            }
        }



        public Hashtable createSettingsTable(string SettingsParams)
        {
            return SharedFunctions.ParseGateway(SettingsParams);
        }

        private void OgonePost(RemotePost post, string OrderID, string PSPID, string paymentURL, 
                                decimal amount, string Currency, string SHAPass, string language, string CartID,
                                string Title, string ClientName, string Email, string Zip, string Addr, string Town, string City, string Phone,
                                string acceptURL, string declineURL, string exceptionURL, string cancelURL,
                                string userLangage, Hashtable additional)
        {
            
            //string OrderID = "1000";
            //string PSPID = "dekbie";
            string amountStr = ((int)(amount * 100)).ToString();

            string SHAtexte = "";

            // order alphabetic
            Hashtable table = new Hashtable(additional);
            table.Add("amount", amountStr);
            table.Add("currency", Currency);
            table.Add("language", language);
            table.Add("orderID", OrderID);
            table.Add("PSPID", PSPID);
            table.Add("TITLE", Title);
            table.Add("PARAMPLUS", "CartID=" + CartID +"&Lang="+userLangage);
            table.Add("acceptURL", acceptURL);
            table.Add("declineURL", declineURL);
            table.Add("exceptionURL", exceptionURL);
            table.Add("cancelURL", cancelURL);
            
            
            table.Add("CN", ClientName);
            table.Add("EMAIL", Email);
            table.Add("ownerZIP", Zip);
            table.Add("owneraddress",Addr);
            table.Add("ownertown",Town);
            table.Add("ownercty",City);
            table.Add("ownertelno",Phone);

            string log = "";
            foreach (string key in table.Keys.OfType<string>().OrderBy(k => k.ToUpper())) {
                string value = (string)table[key];
                if (!string.IsNullOrEmpty(value))
                {
                    SHAtexte = SHAtexte + key.ToUpper() + "=" + value + SHAPass;
                    post.Add(key, value);
                    log = log + key + "=" + value + ",";
                }
            }
            //post.Add("test", SHAtexte);
            post.Add("SHASign",CalcSHA(SHAtexte));
            SharedFunctions.UpdateLog(("Ogone Params = " + log));
            
            //   url = url + "&TITLE="+ SharedFunctions.HTTPPOSTEncode(Title);
            //"&BGCOLOR=%23AF390A&TXTCOLOR=%23CDC40F&TBLBGCOLOR=%23CDC40F&TBLTXTCOLOR=%23000000&BUTTONBGCOLOR=%23763642&BUTTONTXTCOLOR=%23CDC40F&FONTTYPE=Verdana"
            //"&LOGO="
            //"&TP=&ACCEPTURL=&declineurl=&exceptionurl=&cancelurl=&HOME URL=&CATALOGURL=
            //   url = url + "&CN=" + SharedFunctions.HTTPPOSTEncode(ClientName);
            //"&Ecom_BillTo_Postal_Name_First=Bill"
            //"&Ecom_BillTo_Postal_Name_Last=Smith"
            //   url = url + "&EMAIL=" + SharedFunctions.HTTPPOSTEncode(Email);
            //"&WIN3DS="
            //"&PM=&"
            //"BRAND="
            //url = url + "&SHASign=" + CalcSHA(SHAtexte);
            /*
            url = url + "&ownerZIP=" + SharedFunctions.HTTPPOSTEncode(Zip);
            url = url + "&owneraddress=" + SharedFunctions.HTTPPOSTEncode(Addr);
            url = url + "&ownertown=" + SharedFunctions.HTTPPOSTEncode(Town);
            url = url + "&ownercty=" + SharedFunctions.HTTPPOSTEncode(City);
            url = url + "&ownertelno=" + SharedFunctions.HTTPPOSTEncode(Phone);
             */
            //"&alias=&aliasusage=&aliasoperation="
            //"&COM=Three+telephone+cards&COMPLUS=123456789123456789123456789&PARAMPLUS=SessionID%3D126548354%26ShoperID%3D73541312&PARAMVAR=&USERID=&CreditCode=&submit2=+Submit+"

            
        }

        private string CalcSHA(string texte)
        {

            string SHAString = "";
            HashAlgorithm hashAlg = new SHA1Managed();

            using (hashAlg)
            {
                byte[] pwordData = Encoding.Default.GetBytes(texte);

                byte[] hash = hashAlg.ComputeHash(pwordData);

                for (int i = 0; i < hash.Length; i++)
                {
                    SHAString = SHAString + hash[i].ToString("X2");
                }
            }
            return SHAString;

        }

    }
}
